<template>
  <div class="container">
    <el-collapse v-model="activeNames">

      <el-collapse-item :title="`登录信息【${authForm.user.fullName || '未登陆'}】【${authForm.user.hospitalName || '未登陆'}】`" name="1">
        <el-form ref="loginForm" :model="loginForm" label-width="80px">
          <el-form-item label="账号">
            <el-input v-model="loginForm.account"></el-input>
          </el-form-item>
          <el-form-item label="密码">
            <el-input v-model="loginForm.password"></el-input>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="login">登录</el-button>
            <!-- <el-button>取消</el-button> -->
            <el-checkbox v-model="savePassword">记住账号密码</el-checkbox>
          </el-form-item>
        </el-form>
        <el-form ref="authForm" :model="authForm" label-width="80px">
          <el-form-item label="token">
            <el-input type="textarea" v-model="authForm.token"></el-input>
          </el-form-item>
        </el-form>
        <el-table
          :data="[authForm.user]"
          border
          style="width: auto">

          <el-table-column
            width="120"
            label="姓名"
            prop="fullName"/>

          <el-table-column
            width="120"
            label="用户名"
            prop="username"/>

          <el-table-column
            show-overflow-tooltip
            width="120"
            label="机构"
            prop="hospitalName"/>

          <el-table-column
            width="120"
            label="机构编码"
            prop="hospitalSoid"/>

          <el-table-column
            width="120"
            label="身份证"
            prop="cardNumber"/>

          <el-table-column
            width="120"
            label="手机号"
            prop="phoneNumber"/>

          <el-table-column
            show-overflow-tooltip
            width="120"
            label="工号"
            prop="jobNumber"/>

          <el-table-column
            width="120"
            label="userInfoId"
            prop="userInfoId"/>

          <el-table-column
            show-overflow-tooltip
            width="120"
            label="userUid"
            prop="userUid"/>

        </el-table>
      </el-collapse-item>

      <el-collapse-item title="统计报表" name="2">
        <div>
          <el-date-picker
            v-model="datetimerange"
            type="datetimerange"
            size="mini"
            align="right"
            start-placeholder="采集开始日期"
            end-placeholder="采集结束日期"
            :default-time="['00:00:00', '23:59:59']">
          </el-date-picker>
          <el-checkbox v-model="queryChildren">下钻</el-checkbox>
        </div>
        <div style="margin-top: 10px;border: 1px solid #eee;padding: 5px;">
          <el-checkbox v-for="(item, index) in listGuangDe" :key="index" v-model="item.active" @change="cbchange($event, index)">{{ item.hospitalName }}</el-checkbox>
        </div>
        <div style="margin-top: 10px;">
          <el-tag>最大线程数</el-tag>
          <el-input-number v-model="requestThreadTotalMax" size="mini" :disabled="searchLoading" :min="2" :max="5" step-strictly></el-input-number>
          <el-tag>剩余线程：{{ requestThreadTotal }}</el-tag>
        </div>
        <div style="margin-top: 10px;">
          <el-button type="primary" size="mini" @click="search" :loading="searchLoading">查询</el-button>
          <el-button type="primary" size="mini" @click="searchTime(12)" :loading="searchLoading">查询12点</el-button>
          <el-button type="primary" size="mini" @click="searchTime(20)" :loading="searchLoading">查询20点</el-button>
          <el-button type="primary" size="mini" @click="searchTime(21)" :loading="searchLoading">查询21点</el-button>
          <el-tag>查询耗时：{{ timer.timeFormat }}</el-tag>
          <!-- <el-button type="primary" size="mini" @click="testExcelJS">testExcelJS</el-button> -->
          <!-- <el-button type="primary" size="mini" @click="testSheetJS">testSheetJS</el-button> -->
        </div>

        <div style="padding: 10px 0;">
          <el-table
            :data="listGuangDe"
            border
            :row-style="rowStyleFn"
            :cell-style="cellStyleFn"
            @cell-click="cellClick"
            size="mini">

            <el-table-column
              label="单位"
              prop="hospitalName"/>

            <el-table-column
              label="总登记数"
              prop="all">
              <template slot-scope="scope">
                {{ scope.row.allQuery ? scope.row.all : '-' }}
              </template>
            </el-table-column>

            <el-table-column
              label="签收"
              prop="sign">
              <template slot-scope="scope">
                {{ scope.row.signQuery ? scope.row.sign : '-' }}
              </template>
            </el-table-column>
              
            <el-table-column
              label="已出结果"
              prop="hasResult">
              <template slot-scope="scope">
                {{ scope.row.hasResultQuery ? scope.row.hasResult : '-' }}
              </template>
            </el-table-column>

            <el-table-column
              label="未签收"
              prop="noSign">
              <template slot-scope="scope">
                {{ scope.row.noSignQuery ? scope.row.noSign : '-' }}
              </template>
            </el-table-column>

            <el-table-column
              label="操作">
              <template slot-scope="scope">
                <el-button type="success" size="mini" @click="copyLine(scope.$index, scope.row)">复制行</el-button>
              </template>
            </el-table-column>

          </el-table>
          <!-- <el-button type="success" size="mini" @click="copyGuangDe">复制结果</el-button> -->
          <el-button type="success" size="mini" @click="copyResult">复制各乡镇数据</el-button>
          <el-button type="success" size="mini" @click="copySummary">复制汇总表结果</el-button>
        </div>
      </el-collapse-item>

    </el-collapse>
  </div>
</template>

<script>
// import fs from 'fs'
import _path from 'path'
import XLSX from 'xlsx'
// import axios from 'axios'
import request from '@/utils/request'
import Md5 from 'js-md5'
import ExcelJS from 'exceljs'

export default {
  name: 'NucleicAcidRecord',
  data () {
    let s = new Date()
    s.setHours(0)
    s.setMinutes(0)
    s.setSeconds(0)
    s.setMilliseconds(0)
    let e = new Date()
    e.setHours(23)
    e.setMinutes(59)
    e.setSeconds(59)
    e.setMilliseconds(0)
    return {
      activeNames: ['2'],
      loginForm: {
        account: '',
        password: ''
      },
      savePassword: true,
      authForm: {
        token: '',
        user: {}
      },
      hospitalArray: [],
      hospitalArrayProps: {
        label: 'hospitalName',
        children: 'children'
      },
      activeHospital: {},
      datetimerange: [s, e],
      queryChildren: true,
      testProgress: false, // 乡镇检测进度
      // null 全部, 1 未签收, 2 已签收未出结果, "3" 已出结果, "5" 已审核
      checkState: {
        all: null,
        noSign: 1,
        signNoResult: 2,
        hasResult: 3,
        examine: 5
      },
      searchLoading: false,
      listGuangDe: [
        {
          hospitalName: '广德全市',
          hospitalSoid: '1008',
          all: '待查询',
          hasResult: '待查询',
          noSign: '待查询',
          sign: '待查询',
          active: true,
          allQuery: true,
          hasResultQuery: true,
          noSignQuery: true,
          signQuery: true
        },
        {
          hospitalName: '升平街道',
          hospitalSoid: '1008005',
          all: '待查询',
          hasResult: '待查询',
          noSign: '待查询',
          sign: '待查询',
          active: false,
          allQuery: false,
          hasResultQuery: false,
          noSignQuery: false,
          signQuery: false
        },
        {
          hospitalName: '桐汭街道',
          hospitalSoid: '1008006',
          all: '待查询',
          hasResult: '待查询',
          noSign: '待查询',
          sign: '待查询',
          active: false,
          allQuery: false,
          hasResultQuery: false,
          noSignQuery: false,
          signQuery: false
        },
        {
          hospitalName: '桃州镇',
          hospitalSoid: '1008007',
          all: '待查询',
          hasResult: '待查询',
          noSign: '待查询',
          sign: '待查询',
          active: false,
          allQuery: false,
          hasResultQuery: false,
          noSignQuery: false,
          signQuery: false
        },
        {
          hospitalName: '祠山街道',
          hospitalSoid: '1008008',
          all: '待查询',
          hasResult: '待查询',
          noSign: '待查询',
          sign: '待查询',
          active: false,
          allQuery: false,
          hasResultQuery: false,
          noSignQuery: false,
          signQuery: false
        },
        {
          hospitalName: '经开区',
          hospitalSoid: '1008017',
          all: '待查询',
          hasResult: '待查询',
          noSign: '待查询',
          sign: '待查询',
          active: false,
          allQuery: false,
          hasResultQuery: false,
          noSignQuery: false,
          signQuery: false
        },
        {
          hospitalName: '柏垫镇',
          hospitalSoid: '1008011',
          all: '待查询',
          hasResult: '待查询',
          noSign: '待查询',
          sign: '待查询',
          active: false,
          allQuery: false,
          hasResultQuery: false,
          noSignQuery: false,
          signQuery: false
        },
        {
          hospitalName: '邱村镇',
          hospitalSoid: '1008015',
          all: '待查询',
          hasResult: '待查询',
          noSign: '待查询',
          sign: '待查询',
          active: false,
          allQuery: false,
          hasResultQuery: false,
          noSignQuery: false,
          signQuery: false
        },
        {
          hospitalName: '新杭镇',
          hospitalSoid: '1008016',
          all: '待查询',
          hasResult: '待查询',
          noSign: '待查询',
          sign: '待查询',
          active: false,
          allQuery: false,
          hasResultQuery: false,
          noSignQuery: false,
          signQuery: false
        },
        {
          hospitalName: '杨滩镇',
          hospitalSoid: '1008012',
          all: '待查询',
          hasResult: '待查询',
          noSign: '待查询',
          sign: '待查询',
          active: false,
          allQuery: false,
          hasResultQuery: false,
          noSignQuery: false,
          signQuery: false
        },
        {
          hospitalName: '誓节镇',
          hospitalSoid: '1008014',
          all: '待查询',
          hasResult: '待查询',
          noSign: '待查询',
          sign: '待查询',
          active: false,
          allQuery: false,
          hasResultQuery: false,
          noSignQuery: false,
          signQuery: false
        },
        {
          hospitalName: '四合乡',
          hospitalSoid: '1008013',
          all: '待查询',
          hasResult: '待查询',
          noSign: '待查询',
          sign: '待查询',
          active: false,
          allQuery: false,
          hasResultQuery: false,
          noSignQuery: false,
          signQuery: false
        },
        {
          hospitalName: '卢村乡',
          hospitalSoid: '1008009',
          all: '待查询',
          hasResult: '待查询',
          noSign: '待查询',
          sign: '待查询',
          active: false,
          allQuery: false,
          hasResultQuery: false,
          noSignQuery: false,
          signQuery: false
        },
        {
          hospitalName: '东亭乡',
          hospitalSoid: '1008010',
          all: '待查询',
          hasResult: '待查询',
          noSign: '待查询',
          sign: '待查询',
          active: false,
          allQuery: false,
          hasResultQuery: false,
          noSignQuery: false,
          signQuery: false
        },
        {
          hospitalName: '太极洞',
          hospitalSoid: '1008018',
          all: '待查询',
          hasResult: '待查询',
          noSign: '待查询',
          sign: '待查询',
          active: false,
          allQuery: false,
          hasResultQuery: false,
          noSignQuery: false,
          signQuery: false
        }
      ],
      timer: {
        interval: 0,
        start: 0,
        end: 0,
        time: 0,
        timeFormat: 0
      },
      requestEnd: false,
      requestThreadTotal: 5, // 最大同时请求线程数
      requestThreadTotalMax: 5
    }
  },
  watch: {
    listGuangDe (oldValue, newValue) {
      this.$electronStore.set('NucleicAcid.listGuangDe', this.listGuangDe)
    },
    requestThreadTotalMax () {
      this.requestThreadTotalMax = this.requestThreadTotalMax ? this.requestThreadTotalMax : 2
      this.requestThreadTotal = this.requestThreadTotalMax
    }
  },
  created () {
    this.loginForm.account = this.$electronStore.get('NucleicAcid.account')
    this.loginForm.password = this.$electronStore.get('NucleicAcid.password')
    this.authForm.token = this.$electronStore.get('NucleicAcid.token')
    if (this.authForm.token) {
      this.authForm.user = JSON.parse(this.$electronStore.get('NucleicAcid.user')) || {}
      this.getHospital()
    }
    let listGuangDe = this.$electronStore.get('NucleicAcid.listGuangDe')
    if (listGuangDe) {
      this.listGuangDe = listGuangDe
      this.resetList()
    }
  },
  methods: {
    cbchange (active, index) {
      let newItem = this.listGuangDe[index]
      newItem.active = active
      this.$set(this.listGuangDe, index, newItem)
    },

    login () {
      console.log(this.loginForm)
      if (!this.loginForm.account || !this.loginForm.password) {
        this.$message.warning('请输入账号、密码')
        return
      }
      this.$electronStore.delete('NucleicAcid.token')
      request({
        url: 'http://60.173.73.4:8889/login',
        method: 'post',
        data: {
          appAccount: this.loginForm.account,
          randomKey: '',
          userPwd: Md5(this.loginForm.password).toUpperCase(),
          verifyCode: ''
        }
      }).then(res => {
        this.$message.success(res.msg)
        this.authForm.token = res.data.token
        this.authForm.user = res.data.user

        this.$electronStore.set('NucleicAcid.token', this.authForm.token)
        this.$electronStore.set('NucleicAcid.user', JSON.stringify(this.authForm.user))
        if (this.savePassword) {
          this.$electronStore.set('NucleicAcid.account', this.loginForm.account)
          this.$electronStore.set('NucleicAcid.password', this.loginForm.password)
        } else {
          this.$electronStore.delete('NucleicAcid.account')
          this.$electronStore.delete('NucleicAcid.password')
        }
        this.getHospital()
      })
    },

    getHospital () {
      // http://60.173.73.4:8889/api/hospitalDict/getHospital/1008?hospitalType=
      // request({
      //   url: `http://60.173.73.4:8889/api/hospitalDict/getHospital/${this.authForm.user.hospitalSoid}?hospitalType=`,
      //   method: 'post',
      //   data: {}
      // }).then(res => {
      //   // this.$message.success(res.msg)
      //   console.log(res.data)
      //   this.hospitalArray = res.data
      // })
    },

    handleCurrentChange (data, node) {
      console.log(data, node)
      console.log(`hospitalName=${data.hospitalName}`)
      console.log(`hospitalSoid=${data.hospitalSoid}`)
      this.activeHospital = data
    },

    searchTime (hours) {
      let s = new Date()
      s.setHours(0)
      s.setMinutes(0)
      s.setSeconds(0)
      s.setMilliseconds(0)
      let e = new Date()
      e.setHours(hours)
      e.setMinutes(0)
      e.setSeconds(0)
      e.setMilliseconds(0)
      this.datetimerange = [s, e]
      this.search()
    },

    async search () {
      this.searchLoading = true
      // 启动计时器
      this.timer.start = new Date().getTime()
      this.timer.interval = setInterval(() => {
        this.timer.end = new Date().getTime()
        this.timer.time = this.timer.end - this.timer.start
        if (this.timer.time < 1000) {
          this.timer.timeFormat = this.timer.time + '毫秒'
        } else if (this.timer.time < 60000) {
          this.timer.timeFormat = (this.timer.time / 1000).toFixed(2) + '秒'
        } else {
          this.timer.timeFormat = (this.timer.time / 60000).toFixed(0) + '分' + (this.timer.time % 60000 / 1000).toFixed(0) + '秒'
        }
      }, 1000 / 60)
      // 开始查询
      this.resetList()
      const requestArr = []
      for (const item of this.listGuangDe) {
        if (item.active) {
          if (item.allQuery) requestArr.push({item: item, checkState: this.checkState.all})
          if (item.hasResultQuery) requestArr.push({item: item, checkState: this.checkState.hasResult})
          if (item.noSignQuery) requestArr.push({item: item, checkState: this.checkState.noSign})
        }
      }
      this.requestEnd = false
      for (let i = 0; i < requestArr.length; i++) {
        this.requestEnd = i === (requestArr.length - 1)
        await this.query(requestArr[i].item, requestArr[i].checkState)
      }
    },

    query (item, checkState) {
      console.log('query', item, checkState)
      return new Promise(async (resolve, reject) => {
        let d = {
          criteriaMap: {
            search_EQ_hospitalSoid: this.queryChildren ? null : item.hospitalSoid,
            search_LIKE_hospitalSoid: this.queryChildren ? item.hospitalSoid + '%' : null,
            // search_EQ_checkState: checkState, // null 全部, 1 未签收, 2 已签收未出结果, "3" 已出结果, "5" 已审核
            search_GTE_sampleDate: this.datetimerange[0].toISOString(),
            search_LTE_sampleDate: this.datetimerange[1].toISOString(),
            search_EQ_overseas: '',
            search_EQ_regType: '',
            search_EQ_sampTargetId: '',
            search_EQ_samplingLocationDictId: '',
            search_EQ_specimenType: '',
            search_GTE_releaseResultAt: null,
            search_GTE_reportAt: null,
            search_LIKE_createdName: null,
            search_LIKE_nucleicAcidGroupNumber: null,
            search_LIKE_sampleBoxNo: null,
            search_LTE_releaseResultAt: null,
            search_LTE_reportAt: null
          },
          orMap: {
            search_EQ_cardNumber: null,
            search_LIKE_patientName: null
          },
          pagevm: {
            pi: 1,
            ps: 15,
            sort: { nucleicAcidRecordId: 'desc' }
          }
        }
        if (checkState === 1) {
          d.criteriaMap.search_EQ_checkState = 1
        } else if (checkState === 2) {
          d.criteriaMap.search_EQ_checkState = 2
        } else if (checkState === 3) {
          d.criteriaMap.search_GTE_checkState = 3
        } else if (checkState === 5) {
          d.criteriaMap.search_GTE_checkState = 5
        }
        // 判断线程池
        if (this.requestThreadTotal > 0) {
          this.doRequest(item, checkState, d)
          resolve()
        } else {
          for (let i = 1; i > 0; i--) {
            console.log('等待中...')
            await this.sleep(1000)
            if (this.requestThreadTotal < 1) {
              i++
            }
          }
          this.doRequest(item, checkState, d)
          resolve()
        }
      })
    },

    doRequest (item, checkState, params) {
      this.requestThreadTotal--
      request({
        url: 'http://60.173.73.4:8889/api/nucleicAcidRecord/queryNucleicAcidRecord',
        method: 'post',
        data: params
      }).then(res => {
        if (checkState === this.checkState.all) {
          item.all = res.data.totalElements
        } else if (checkState === this.checkState.noSign) {
          item.noSign = res.data.totalElements
        } else if (checkState === this.checkState.signNoResult) {
          item.signNoResult = res.data.totalElements
        } else if (checkState === this.checkState.hasResult) {
          item.hasResult = res.data.totalElements
        } else if (checkState === this.checkState.examine) {
          item.examine = res.data.totalElements
        }
        item.sign = isNaN(item.all - item.noSign) ? '请稍后' : item.all - item.noSign
      }).finally(() => {
        this.requestThreadTotal++
        if (this.requestEnd && this.requestThreadTotal === this.requestThreadTotalMax) {
          this.$message.success('查询已完成')
          this.searchLoading = false
          // 清除计时器
          clearInterval(this.timer.interval)
        }
      })
    },

    sleep (ms) {
      return new Promise(resolve => setTimeout(() => { resolve() }, ms))
    },

    resetList () {
      for (const item of this.listGuangDe) {
        item.all = '待查询'
        item.hasResult = '待查询'
        item.noSign = '待查询'
        item.sign = '待查询'
      }
    },

    // 复制行
    copyLine (index, row) {
      let text = row.all + '\t' + row.sign + '\t' + row.hasResult + '\t' + row.noSign
      this.$electron.clipboard.writeText(text)
      this.$message.success('已复制')
    },

    // 复制各乡镇数据
    copyResult () {
      let text = ''
      this.listGuangDe.forEach((item, n) => {
        if (item.active && item.hospitalSoid !== '1008') {
          text += item.all + '\r'
        }
      })
      this.$electron.clipboard.writeText(text)
      this.$message.success('已复制')
    },

    // 复制汇总表数据
    copySummary () {
      let text = ''
      let sum = 0
      let guangdeAll = 0
      this.listGuangDe.forEach((item, n) => {
        if (item.active) {
          if (item.hospitalSoid !== '1008') {
            text += item.all + '\r'
            sum += item.all
          } else {
            guangdeAll = item.all
          }
        }
      })
      text += sum + '\r'
      text += guangdeAll + '\r'
      this.$electron.clipboard.writeText(text)
      this.$message.success('已复制')
    },

    async testExcelJS () {
      // 模拟时间
      let h = 12
      // 模拟数据start
      for (const item of this.listGuangDe) {
        item.all = 4
        item.hasResult = 2
        item.noSign = 3
        item.sign = 1
      }
      for (const item of this.list) {
        item.all = 7
      }
      // 模拟数据end
      let todayStr = this.$moment().format('M月DD日')
      console.log(todayStr)
      let dir = 'C:/Users/Administrator/Desktop/核酸数据/统计表'
      let filename = _path.join(dir, '/核酸采样进度登记表22.09.26.xlsx')
      let filename2 = _path.join(dir, '/test核酸采样进度登记表22.09.26.xlsx')
      console.log(filename)
      // 打开Excel
      const workbook = new ExcelJS.Workbook()
      await workbook.xlsx.readFile(filename)
      // 在加载时强制工作簿计算属性
      workbook.calcProperties.fullCalcOnLoad = true
      console.log(workbook)
      // 修改Excel
      // const summarySheet = workbook.getWorksheet('汇总')
      const tempSheet = workbook.getWorksheet('每日模板')
      const todaySheet = workbook.addWorksheet(todayStr)
      todaySheet.model = Object.assign(tempSheet.model, {
        mergeCells: tempSheet.model.merges
      })
      console.log(todaySheet.name)
      todaySheet.name = todayStr
      const cellA1 = todaySheet.getCell('A1')
      cellA1.value = todayStr
      // 写入数据
      for (const item of this.listGuangDe) {
        if (h === 12) {
          todaySheet.getCell(item.allPos12).value = item.all
          todaySheet.getCell(item.hasResultPos12).value = item.hasResult
          todaySheet.getCell(item.noSignPos12).value = item.noSign
          todaySheet.getCell(item.signPos12).value = item.sign
        } else if (h === 20) {
          todaySheet.getCell(item.allPos20).value = item.all
          todaySheet.getCell(item.hasResultPos20).value = item.hasResult
          todaySheet.getCell(item.noSignPos20).value = item.noSign
          todaySheet.getCell(item.signPos20).value = item.sign
        }
      }
      for (const item of this.list) {
        if (h === 12) {
          todaySheet.getCell(item.allPos12).value = item.all
        } else if (h === 20) {
          todaySheet.getCell(item.allPos20).value = item.all
        }
      }
      // 保存修改后的文件
      await workbook.xlsx.writeFile(filename2)
      console.log('finished')
    },

    // 没有样式
    testSheetJS () {
      let yesterday = this.$moment().subtract(1, 'day').format('M月DD日')
      console.log(yesterday)
      let today = this.$moment().format('M月DD日')
      console.log(today)
      let dir = 'C:/Users/Administrator/Desktop/核酸数据/统计表'
      let filename = _path.join(dir, '/核酸采样进度登记表22.09.26.xlsx')
      let filename2 = _path.join(dir, '/test核酸采样进度登记表22.09.26.xlsx')
      console.log(filename)
      // 打开Excel
      let workbook = XLSX.readFile(filename)
      console.log(workbook)
      // 修改Excel
      XLSX.writeFile(workbook, filename2, {})
    },

    rowStyleFn ({ row }) {
      return row.active ? {} : { display: 'none' }
    },

    cellStyleFn ({row, column, rowIndex, columnIndex}) {
      const disableStyle = {
        background: '#ccc'
      }
      switch (column.property) {
        case 'hospitalName': break
        case 'all':
          if (!row.allQuery) return disableStyle
          break
        case 'hasResult':
          if (!row.hasResultQuery) return disableStyle
          break
        case 'noSign':
          if (!row.noSignQuery) return disableStyle
          break
        case 'sign':
          if (!row.signQuery) return disableStyle
          break
      }
    },

    cellClick (row, column, cell, event) {
      switch (column.property) {
        case 'hospitalName': break
        case 'all':
          row.allQuery = !row.allQuery
          break
        case 'hasResult':
          row.hasResultQuery = !row.hasResultQuery
          break
        case 'noSign':
          row.noSignQuery = !row.noSignQuery
          break
        case 'sign':
          row.signQuery = !row.signQuery
          break
      }
      let item = this.listGuangDe[0]
      this.$set(this.listGuangDe, 0, item)
    }
  }
}
</script>

<style lang="less" scoped>
.container {
  width: 90%;
  padding: 0 5%;
  height: 100%;
  overflow-y: scroll;
  -webkit-user-select: text;
}
</style>
